#include<iostream>
using namespace std;
class MY
{
    char _a;
    char _b;
public:
    MY(char a = ' '):_a(a),
	    _b(a) {}
};
class Date
{
    //这其实只是成员变量的声明定义部分在初始化列表处，如果这里有缺省赋值的话就是用把缺省值用在初始化列表的
    //初始化
    int _year = 2001;
    int _month;
    int _day;
    int * _testptr;
    MY n1;

public:
/////////////////////////////////////////////
//构造函数
//构造函数是默认成员函数之一，可以编译器自动生成
//参数随意设置，无参，全缺省和编译器自动生成的都是默认构造函数
//在实例化的时候自动调用，并不需要返回之类的，没有返回值
//支持重载，函数名是类名，一般来说编译器自动生成的对内置类型不进行处理，自定义类型调用默认构造
//一般来讲，有对应的内置类型都需要写构造函数，自定义类型就是调用构造函数
//如果全是自定义类型就不需要写
//构造函数的调用如果是不加括号传参进行调用，就会调用默认构造函数进行构造
///////////////////////////////////////////////
//初始化列表可以加冒号然后 成员 + （初始化的内容）用逗号进行成员初始化进行隔开
    Date(int year = 2000,int month = 1,int day = 1):_testptr(nullptr),n1('0')
    {
        _year = year;
        _month = month;
        _day = day;
    }
    //构析函数
    //函数名~类名
    //无法发生重载
    //不用返回值，和参数，构析函数在对象出了生命周期自动调用
    //构析函数，内置类型不进行处理，自定义类型调用 对应的构析函数
    ~Date()
    {
        _year = 0;
        _month = 0;
        _day = 0;
	    _testptr = nullptr;

    }
    //copy constructor function
    //This fuction is result that constructor overloading generate.it has many unique character,such as:
    //1.copy constructor function have only one parameters which must other constant type object reference
    //2.而且不能是传值方式如果是传值方式的话会发生无限递归，因为，是传值的话传参的时候还是会将原来对象的拷贝传给临时变量
    //临时变量传给参数是还会发生拷贝，无限调用
    //3.若没有显式定义的话在编译器中会自动生成但是只能进行浅拷贝，无法对一些额外空间进行相应的拷贝
    //
    Date(const Date & sourse)
    {
	    _year = sourse._year;
	    _month = sourse._month;
	    _day = sourse._day;
	    n1 = sourse.n1;
	    _testptr = sourse._testptr;
    }
    //赋值操作符重载
    //赋值操作符重载在类中也是一个默认成员函数不能在类外边进行定义，如果进行定义的话
    Date &  operator=(const Date & n2)
    {
        _year = n2._year;
        _month = n2._month;
        _day = n2._day;
        _testptr = n2. _testptr;
        n1 = n2.n1;
        return *this;
    }
    bool operator!=(const Date& d2)
    {
        return !((*this) == d2);
    }
    bool operator==(const Date & d2) const 
    {
        return (_year == d2._year) && ( _month == d2._month) && (_day == d2._day);
    }
    bool operator<=(const Date & d2) const 
    {
        return !(_year > d2._year) || !(_month > d2._month) || !(_day > d2._day);
    }
    bool operator>(const Date & d2) const
    {
        return !((*this) <= d2);
    }
    bool operator<(const Date & d2)
    {
        return !((*this) == d2 || (*this) > d2);
    }
    friend ostream &  operator<<(ostream & in,Date & d2);
    Date * operator&()
    {
        return this;
    }
    int Get_month_day(int month,bool judge)
    {
        if(judge)
        {
            return r_year[month - 1];
        }
        return p_year[month - 1];
    }
    bool Judge_year(int year)
    {
        if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        {
            return true;
        }
        return false;
    }
    Date operator+(int a)
    {
        Date tem = *this;
        tem._day += a;
        //int carry = 0;
        bool tem_judge = Judge_year(_year);
        while(tem._day > Get_month_day(tem._month,tem_judge))
        {

           tem._day -= Get_month_day(tem._month,tem_judge);
            tem._month++;
            if(tem._month > 12)
            {
                tem._month -= 12;
                tem._year++;
            }
            tem_judge = Judge_year(tem._year);
        }
        
        return tem;
    }
    Date& operator++(int)
    {
        *this = (*this) + 1;
        return *this;
    }
    Date operator++()
    {
        Date tmp = *this;
        *this = *this + 1;
        return tmp;
    }
    int operator-(Date & d2 )
    {
        Date d3 = *this;
        int res = 0;
        while(d3 != d2)
        {
            d3._day--;
            res++;
            while(!d3._day)
            {
                d3._month--;
                while(!d3._month)
                {
                    d3._month = 12;
                    d3._year--;
                }
                d3._day = Get_month_day(d3._year,Judge_year(d3._year));

            }
        }
    return res;
    }
    static int r_year[];
    static int p_year[];
};
// int Date :: i = 0;
int Date:: r_year[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
int Date :: p_year[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

ostream &  operator<<(ostream&in,Date & d2)
{
	in << d2._year << ' ' <<d2._month <<' ' << d2._day << endl;
    return in;
}      
int main()
{
	Date s1;
    Date s2(2023,6,9);
    Date * a = new Date();//new会返回一个指针，而java的是直接new一个类
	cout << s1;
    if(s1 <= s2)
    {
        cout << "ture" << endl;
    }
    s1 = s1 + 1000;
    cout << s1 << endl;
    delete a;
	return 0;
}
